#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
网络配置监控工具
用于监控网络配置变化，特别是在安装代理软件后
"""

import subprocess
import json
import time
import os
from datetime import datetime
from pathlib import Path

class NetworkMonitor:
    def __init__(self, backup_dir="network_backup_20250921_210643"):
        self.backup_dir = Path(backup_dir)
        self.monitor_log = "network_monitor.log"
        self.redis_host = "test-redis.oyumwu.clustercfg.apne1.cache.amazonaws.com"
        
    def log_message(self, message):
        """记录日志消息"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"[{timestamp}] {message}\n"
        with open(self.monitor_log, "a", encoding="utf-8") as f:
            f.write(log_entry)
        print(log_entry.strip())
    
    def run_command(self, command):
        """执行系统命令"""
        try:
            result = subprocess.run(command, shell=True, capture_output=True, text=True)
            return result.stdout, result.stderr, result.returncode
        except Exception as e:
            return "", str(e), 1
    
    def check_dns_changes(self):
        """检查DNS配置变化"""
        self.log_message("检查DNS配置...")
        
        # 获取当前DNS配置
        stdout, stderr, code = self.run_command("scutil --dns")
        if code != 0:
            self.log_message(f"❌ 获取DNS配置失败: {stderr}")
            return False
        
        # 与备份的DNS配置比较
        backup_dns_file = self.backup_dir / "dns_config.txt"
        if backup_dns_file.exists():
            with open(backup_dns_file, "r") as f:
                backup_dns = f.read()
            
            if stdout != backup_dns:
                self.log_message("⚠️  DNS配置已发生变化！")
                # 保存当前DNS配置
                with open("current_dns_config.txt", "w") as f:
                    f.write(stdout)
                self.log_message("当前DNS配置已保存到: current_dns_config.txt")
                return True
            else:
                self.log_message("✅ DNS配置未发生变化")
                return False
        else:
            self.log_message("❌ 找不到备份的DNS配置文件")
            return False
    
    def check_proxy_changes(self):
        """检查代理设置变化"""
        self.log_message("检查代理设置...")
        
        # 检查各种代理设置
        proxy_services = ["Wi-Fi", "Ethernet", "Thunderbolt Bridge"]
        changes_detected = False
        
        for service in proxy_services:
            # 检查HTTP代理
            stdout, stderr, code = self.run_command(f"networksetup -getwebproxy \"{service}\"")
            if "Enabled: Yes" in stdout:
                self.log_message(f"⚠️  {service} 启用了HTTP代理")
                changes_detected = True
            
            # 检查HTTPS代理
            stdout, stderr, code = self.run_command(f"networksetup -getsecurewebproxy \"{service}\"")
            if "Enabled: Yes" in stdout:
                self.log_message(f"⚠️  {service} 启用了HTTPS代理")
                changes_detected = True
            
            # 检查SOCKS代理
            stdout, stderr, code = self.run_command(f"networksetup -getsocksfirewallproxy \"{service}\"")
            if "Enabled: Yes" in stdout:
                self.log_message(f"⚠️  {service} 启用了SOCKS代理")
                changes_detected = True
        
        if not changes_detected:
            self.log_message("✅ 未检测到代理设置变化")
        
        return changes_detected
    
    def check_routing_changes(self):
        """检查路由表变化"""
        self.log_message("检查路由表...")
        
        # 获取当前路由表
        stdout, stderr, code = self.run_command("netstat -rn")
        if code != 0:
            self.log_message(f"❌ 获取路由表失败: {stderr}")
            return False
        
        # 与备份的路由表比较
        backup_routing_file = self.backup_dir / "routing_table.txt"
        if backup_routing_file.exists():
            with open(backup_routing_file, "r") as f:
                backup_routing = f.read()
            
            if stdout != backup_routing:
                self.log_message("⚠️  路由表已发生变化！")
                # 保存当前路由表
                with open("../../current_routing_table.txt", "w") as f:
                    f.write(stdout)
                self.log_message("当前路由表已保存到: current_routing_table.txt")
                return True
            else:
                self.log_message("✅ 路由表未发生变化")
                return False
        else:
            self.log_message("❌ 找不到备份的路由表文件")
            return False
    
    def check_hosts_changes(self):
        """检查hosts文件变化"""
        self.log_message("检查hosts文件...")
        
        # 获取当前hosts文件
        stdout, stderr, code = self.run_command("cat /etc/hosts")
        if code != 0:
            self.log_message(f"❌ 获取hosts文件失败: {stderr}")
            return False
        
        # 与备份的hosts文件比较
        backup_hosts_file = self.backup_dir / "hosts.txt"
        if backup_hosts_file.exists():
            with open(backup_hosts_file, "r") as f:
                backup_hosts = f.read()
            
            if stdout != backup_hosts:
                self.log_message("⚠️  hosts文件已发生变化！")
                # 保存当前hosts文件
                with open("current_hosts.txt", "w") as f:
                    f.write(stdout)
                self.log_message("当前hosts文件已保存到: current_hosts.txt")
                return True
            else:
                self.log_message("✅ hosts文件未发生变化")
                return False
        else:
            self.log_message("❌ 找不到备份的hosts文件")
            return False
    
    def test_basic_connectivity(self):
        """测试基本网络连接"""
        self.log_message("测试基本网络连接...")
        
        # 测试DNS解析
        stdout, stderr, code = self.run_command("nslookup google.com")
        if code == 0:
            self.log_message("✅ DNS解析正常")
        else:
            self.log_message("❌ DNS解析失败")
        
        # 测试基本网络连接
        stdout, stderr, code = self.run_command("ping -c 1 8.8.8.8")
        if code == 0:
            self.log_message("✅ 基本网络连接正常")
        else:
            self.log_message("❌ 基本网络连接失败")
    
    def generate_restore_instructions(self):
        """生成恢复指导"""
        self.log_message("生成恢复指导...")
        
        instructions = f"""
网络配置恢复指导
================
时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

如果网络出现问题，请按以下步骤恢复：

1. 快速恢复（推荐）:
   cd {self.backup_dir}
   ./restore.sh

2. 手动恢复DNS:
   sudo dscacheutil -flushcache
   sudo killall -HUP mDNSResponder

3. 重置网络设置:
   sudo networksetup -setdnsservers "Wi-Fi" "Empty"
   sudo networksetup -setdhcp "Wi-Fi"

4. 检查代理设置:
   networksetup -listallnetworkservices
   networksetup -getwebproxy "Wi-Fi"
   networksetup -getsecurewebproxy "Wi-Fi"

5. 如果问题严重，可以重置网络:
   sudo rm -rf /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist
   sudo rm -rf /Library/Preferences/SystemConfiguration/preferences.plist
   sudo reboot

6. 恢复后测试Redis连接:
   ping {self.redis_host}
   nc -z -v {self.redis_host} 6379

注意: 恢复前请确保已配置Redis服务器的公钥认证
"""
        
        with open("../../restore_instructions.txt", "w", encoding="utf-8") as f:
            f.write(instructions)
        
        self.log_message("恢复指导已保存到: restore_instructions.txt")
    
    def run_monitor(self):
        """运行网络监控"""
        self.log_message("开始网络配置监控...")
        self.log_message(f"备份目录: {self.backup_dir}")
        self.log_message(f"Redis服务器: {self.redis_host}")
        
        changes_detected = False
        
        # 检查各项配置
        if self.check_dns_changes():
            changes_detected = True
        
        if self.check_proxy_changes():
            changes_detected = True
        
        if self.check_routing_changes():
            changes_detected = True
        
        if self.check_hosts_changes():
            changes_detected = True
        
        # 测试基本连接
        self.test_basic_connectivity()
        
        # 生成恢复指导
        self.generate_restore_instructions()
        
        if changes_detected:
            self.log_message("⚠️  检测到网络配置变化！请检查是否需要恢复")
        else:
            self.log_message("✅ 网络配置正常，未检测到异常变化")
        
        self.log_message("监控完成")

if __name__ == "__main__":
    monitor = NetworkMonitor()
    monitor.run_monitor()
